PATHMac OS 8 Developer Documentation > Human Interface Toolbox > Menu Manager >

Mac OS 8 Menu Manager Reference


Defining Your Own Contextual Menu Plug-In

The following Menu Manager methods for defining your own contextual menu plug-in are new with Appearance Manager 1.0:


Note

A contextual menu plug-in is implemented as a SOMObject object inside a shared library. (SOMObjects for the Mac OS platform is the Mac OS implementation of the System Object Model.) Typically your development environment can compile directly to a SOMObject object, so you do not need to create your own SOM interfaces.

A contextual menu plug-in is a subclass of AbstractCMPlugin : SOMObject . It consists of four methods described above. Each subclass of the AbstractCMPlugin must have an extended 'cfrg' resource, through which it identifies itself as a SOMObject object which derives from the AbstractCMPlugin class. See Mac OS Runtime Architectures for information about the extended 'cfrg' resource.

In addition you must register the plug-in class as a SOMObject object so that the Menu Manager can instantiate it by name. Typically you can do this in a fragment's initialization function.

Listing 1-1 shows a sample initialization function that registers the plug-in.


Listing 1-1  Registering a contextual menu plug-in

pascal OSErr MyPluginInitialize(CFragInitBlockPtr init)
{
    /* If your compiler creates a default initialization function,*/
    /* you should call it here */

    /* Now register our class with SOM */
        somNewClass(MyPlugIn);

    return noErr;
}

The class declaration for a contextual menu definition plug-in is as follows:

class AbstractCMPlugin: SOMObject
{
    OSStatus Initialize(FSSpec *inFileSpec);
    OSStatus ExamineContext(AEDesc* inContextDescriptor,
                    SInt32 inTimeOutInTicks
                    AEDescList* ioCommandPairs,
                    Boolean* outNeedMoreTime);
    OSStatus HandleSelection(AEDesc* inContextDescriptor, SInt32
                    inCommandID);
    OSStatus PostMenuCleanup(void);
}

When writing your own contextual menu plug-in, you must follow this declaration and include the specified methods. The following sections describe these methods in detail.


Initialize

Performs any required plug-in initialization. If you write a contextual menu plug-in, you may include an Initialize method with the following form:

OSStatus Initialize (FSSpec *inFileSpec);
inFileSpec
A pointer to a file system specification record for the file that contains the plug-in.
method result
A result code. See Result Codes for a list of possible values. If this value is not noErr then the Menu Manager does not use the plug-in.

DISCUSSION

The Initialize method is called when the Menu Manager builds its registry of available plug-ins (typically at system startup). You should use the Initialize method to check for available resources before the plug-in is actually required. To maintain a small memory footprint, the Initialize method should not allocate any memory, buffers, or so on. Instead, you should allocate memory as needed when examining the context or acting on the selection.


VERSION NOTES

Available with Appearance Manager 1.0 and later.


ExamineContext

Examines the context chosen by the user and determines possible menu commands appropriate to the context. If you write a contextual menu plug-in, it must contain an ExamineContext method with the following form:

OSStatus ExamineContext (AEDesc* inContextDescriptor,
                     SInt32 inTimeOutInTicks,
                     AEDescList* ioCommandPairs,
                     Boolean* outNeedMoreTime);
inContextDescriptor
The context chosen by the user. The Menu Manager passes this in the form of a pointer to an Apple Event descriptor. See Inside Macintosh: Interapplication Communication for information about the form of this descriptor. If there is no selection to examine, the pointer is NULL .
inTimeOutInTicks
The amount of time the plug-in is allowed to examine the context and create menu items.
ioCommandPairs
A pointer to an Apple Event descriptor list containing the commands allowed for this context.
outNeedMoreTime
Not currently used.
method result
A result code. See Result Codes for a list of possible values. If this value is not noErr then the Menu Manager does not use the plug-in in this case. However, it will call ExamineContext again the next time a contextual menu is invoked.

DISCUSSION

When the user activates a contextual menu, each module in the registry has its ExamineContext method called so it can inspect the context and add menu items as appropriate. After examining the context, the plug-in should then fill the AEDescList array with every command that it wants to add to the menu. This AEDescList will be created and disposed of for the plug-in; it will be empty when the plug-in receives it.

Each menu command that the plug-in can perform on the selection is described in an AERecord with two keyword-specified descriptor records. The structure of the AERecord is shown in Figure 1-1 .


Figure 1-1  A menu command list in the AEDescList array

The first descriptor ( keyAEName ) is of typeIntlText and contains the text of the menu item to be added to the menu. The second descriptor ( keyContextualMenuCommandID ) is of type typeLongInteger and must contain a value specific to the plug-in that uniquely identifies this menu item.

If a plug-in wants to display a submenu for a particular menu item, it must use a variation of the AERecord used to describe a normal menu item. Figure 1-2 shows this variation.


Figure 1-2  A menu record showing submenus

The first descriptor ( keyAEName ) is the same, but the second descriptor uses a different keyword ( keyContextualMenuSubmenu ) and is of type typeAEList . It must contain an AEDescList with an AERecord for every command to be added to the submenu. Submenu items can themselves have submenus by recursively using this technique. The depth of the submenus is limited only by the constraints of the Menu Manager.


VERSION NOTES

Available with Appearance Manager 1.0 and later.


HandleSelection

Executes the contextual menu item chosen by the user. If you write a contextual menu plug-in, it must contain a HandleSelection method with the following form:

OSStatus HandleSelection(AEDesc* inContextDescriptor,
                     SInt32 inCommandID);
inContextDescriptor
The context chosen by the user. This data is the same as that passed in the inContextDescriptor parameter for the ExamineContext method. The Menu Manager passes this in the form of a pointer to an Apple Event descriptor. See Inside Macintosh: Interapplication Communication for information about the form of this descriptor.
inCommandID
A long integer assigned to the chosen menu item via the keyContextualMenuCommandID descriptor, passed in by the Menu Manager.
method result
A result code. See Result Codes for a list of possible values. If this value is not noErr then the Menu Manager does not use the plug-in in this case. However, it will call HandleSelection again the next time an action is selected.

DISCUSSION

If one of the plug-in's menu items is chosen, the Menu Manager calls the plug-in's HandleSelection method to execute the action. The plug-in should then perform the appropriate action.


VERSION NOTES

Available with Appearance Manager 1.0 and later.


PostMenuCleanup

Performs any necessary cleanup when the contextual menu is dismissed. If you write a contextual menu plug-in, it must contain a PostMenuCleanup method with the following form:

OSStatus PostMenuCleanup(void);
method result
A result code. See Result Codes for a list of possible values.

DISCUSSION

When a contextual menu is dismissed (regardless of whether or not the user made a selection), the Menu Manager calls each plug-in's PostMenuCleanup method. The PostMenuCleanup method should do any necessary cleanup or memory deallocation. For example, a plug-in that allocated a buffer in the ExamineContext method should dispose of that buffer when PostMenuCleanup is called.


VERSION NOTES

Available with Appearance Manager 1.0 and later.


© 1998 Apple Computer, Inc. - (Last Updated 19 Nov 98)